//1.创建Node节点类Node
class Node<T> {
    value: T
    next: Node<T> | null = null 
    constructor(value: T) {
        this.value = value
    }
}

//2.创建LinkedList的类
class LinkList<T> {
    head: Node<T> | null = null
    private size: number = 0
    


    get length(){
        return this.size
    }

    //封装私有方法
    //根据position获取当前的节点(不是节点的value,而是获取节点)
    private getNode(position:number):Node<T> | null{
        let index = 0;
        let current = this.head;
        while(index++ < position && current){
            current = current.next
        }
        return current
    }

    //追加节点,只在最后的位置插入
    append(value:T){
        //1.根据value创建一个新节点
        const newNode = new Node(value)
        //2.判断this.head是否为null
        if(!this.head){
            this.head = newNode
        }else{
            let current = this.head;
            while(current.next){
                current = current.next
            }
            current.next = newNode
        }
        //3.size++
        this.size++
    }

    //遍历链表的方法
    traverse(){
        //用来存储遍历出的节点
        const values: T[] = []
        //拿到第一个节点
        let current = this.head
        //当节点不为空时,一直向数组中追加节点
        while(current){
            values.push(current.value)
            current = current.next
        }
        //打印
        console.log(values.join('->'))
    }

    //插入方法
    insert(value: T,position: number):boolean{
        //插入位置越界的时候
        if(position<0 || position >this.size) return false
        const newNode = new Node(value)
        //如果插入位置在第一个
        if(position === 0 ) {
            //将新节点的下一个节点指向之前的头部
            newNode.next = this.head
            //将头部指向新节点
            this.head = newNode
        }else{
            
            const previous = this.getNode(position - 1)
            //将新节点的next指向要插入位置的老节点
            newNode.next = previous!.next
            //将老节点的前一个节点的next指向新节点
            previous!.next = newNode
        }
        this.size++
        return true
    }

    //移除方法
    removeAt(position:number):T | null{
        //1、越界的判断
        if(position < 0 || position >= this.size) return null
        let current = this.head
        //判断删除的是否是第一个节点
        if(position === 0){
            this.head = current?.next ?? null
        }else{
            //找到要删除节点的前一个节点
            const previous = this.getNode(position - 1)
            //找到需要的节点
            previous!.next = previous?.next?.next ?? null
            return previous?.next?.value ?? null
        }
        this.size--

        return current?.value ?? null
    }

    //获取方法(根据索引获取对应的位置)
    get(position:number):T | null{
        //越界问题
        if(position < 0 || position >= this.size) return null;
        
        //查找元素
        const current = this.getNode(position)
        return current?.value ?? null
    }
    //更新方法
    update(value:T,position:number):boolean{
        if(position<0 || position >=this.size) return false
        //获取对应的节点，直接访问即可
        const current = this.getNode(position)
        current!.value = value
        return true
    }
}

const linkedList = new LinkList<string>()
// console.log('------------------测试append----------------')
linkedList.append('aaa')
linkedList.append('bbb')
linkedList.append('ccc')
linkedList.append('ddd')
linkedList.traverse()

// console.log('------------------测试insert----------------')
linkedList.insert('555',2)
linkedList.insert('666',0)
linkedList.traverse()

console.log('------------------测试removeAt----------------')
console.log(linkedList.removeAt(2))
linkedList.traverse()
console.log(linkedList.removeAt(3))
linkedList.traverse()

console.log('------------------测试get----------------')
console.log(linkedList.get(0))
console.log(linkedList.get(1))
console.log(linkedList.get(2))

export {}